import re


class foxgloveTransformTool:
    def __init__(self):
        super(foxgloveTransformTool, self).__init__()
        self.moduleName="DDS_SP_PK_STATEMANAGER_ALL_INPUT"
        open('resCode.txt', 'w+',encoding='utf-8')
        self.mainStructList=[]#代码包含的所有的结构体
        self.writeStructQueue=[]

        self.ReadSentencesList=[]
        #IDL结构体定义表
        self.IDLStructMap={}
        self.IDLEnumMap = {}
        #IDL基础类型映射表
        self.IDLReflectMap={
            "uint8_t":"octet",
            "SP_ID":"unsigned long long",
            "uint8": "octet",
            "uint16_t":"short",
            "uint16":"short",
            "int32_t": "long",
            "uint32_t": "unsigned long",
            "uint32": "unsigned long",
            "int64_t": "long long",
            "int": "long long",
            "uint64_t": "unsigned long long",
            "float": "float",
            "double": "double",
            "long double": "long double",
            "std::string": "string",
            "boolean": "boolean",
            "bool": "boolean",
            }


    #为一个变量生成读入赋值语句
    def generateReadfun(self,varName:str):
        str=f"dstdata->{varName} = outputdata.{varName}();\n"
        return str
    
    #为一个变量生成写入赋值语句
    def generateWritefun(self,varName:str):
        str=f"outputdata.{varName}()=data->{varName};\n"
        return str

    # 识别一段变量定义代码
    def parseParagraph(self, paragraph: str):
        varDefinitionList=[]
        sentenceList = paragraph.split("\n")
        for sen in sentenceList:
            if sen.strip() != "":
                sen=sen.strip()
                # 删除注释和分号后的内容 删除\t
                sen = sen.split("//")[0]
                sen = sen.split("/*")[0]
                sen = sen.split(";")[0]
                if sen!= "" and sen.strip()!="":
                    varDefinition=self.transformSentence(sen)
                    varDefinitionList.append(varDefinition)
        return varDefinitionList

    # 识别一条变量定义代码
    def transformSentence(self,sentence:str):
        #识别变量类型的定义
        # eg: uint8_t up
        word=sentence.replace("\t"," ")
        words=word.split(" ")
        # 变量类型的拼接 空格为分割符
        #  eg: unsigned int 转化为 unsigned int
        varType = " ".join(words[:-1])
        varType=varType.strip()
        varName=words[-1]#变量名

        #根据类型映射表和结构体定义表转换类型并返回
        if varType in self.IDLReflectMap.keys():
            reflectType=self.IDLReflectMap[varType]
            return  {'varType':reflectType,'varName':varName}
        elif varType in self.IDLStructMap.keys():
            #未识别类型是已定义的结构体类型
            return  {'varType':varType,'varName':varName}
        elif varType in self.IDLEnumMap.keys():
            # 未识别类型是枚举类型
            return {'varType': "unsigned long", 'varName': varName}
        else:
            #未识别类型 未被定义
            print(f'未识别类型{varType},变量名{varName}.')
            return {'varType':varType,'varName':varName}


    #检查结构体内部的变量类型是否都已被定义
    def checkAllDefined(self,structName:str):
        varList=self.IDLStructMap[structName]
        for var in varList:
            if var['varType'] not in self.IDLStructMap.keys() and var['varType'] not in self.IDLReflectMap.values():
                return  False
        return True
    
       #检查结构体内部的变量类型是否都已被定义且确定写入 true为尚未完成
    def checkNoAllWrited(self,structName:str):
        varList=self.IDLStructMap[structName]
        for var in varList:
            if var['varType'] not in self.writeStructQueue and var['varType'] not in self.IDLReflectMap.values():
                return  True
        return False

    #从全部的代码中识别出结构体定义代码
    def parseCode(self,code:str):
        res = re.findall(r"typedef\s+enum\s+(\S*)\s*\{(.*?)\}[^\S\n]?(\S+);", code, re.DOTALL)
        for t in res:
            enumContent = t[1]
            enumPrimeName = t[0]
            enumName = t[2]
            self.IDLEnumMap[enumName] = []
        res=re.findall(r"typedef\s+struct\s+(\S+)\s*\{(.*?)\}[^\S\n]?(\S+);",code, re.DOTALL)
        for t in res:
            structContent=t[1]
            structPrimeName=t[0]
            structName=t[2]
            varDefinitionList=self.parseParagraph(structContent)
            self.IDLStructMap[structName]=varDefinitionList
            self.mainStructList.append(structName)

    # 生成IDL定义代码
    def generateIDL(self):
        with open('resCode.txt', 'w+', encoding='utf-8') as fWrite:
            fWrite.write(f"\n\n//IDL定义代码\n")
            for structName in self.writeStructQueue:
                fWrite.write(f"struct {structName}\n")
                fWrite.write("{\n")
                for varDefinition in self.IDLStructMap[structName]:
                    fWrite.write(f'\t{varDefinition["varType"]} {varDefinition["varName"]};\n')
                fWrite.write("};\n")

    #生成Wirite和read函数定义
    def generateFun(self):
        with open('resCode.txt', 'a+', encoding='utf-8') as fWrite:
            fWrite.write(f"\n\n//Write赋值函数调用代码\n")
            for structName in self.writeStructQueue:
                vars=self.IDLStructMap[structName]
                fWrite.write(f"\nvoid convert{structName}Write({structName}* data,{self.moduleName}::{structName}& outputdata)\n")
                fWrite.write('{\n')
                for var in vars:
                    varName = var["varName"]
                    varType=var["varType"]
                    if varType in self.IDLReflectMap.values():#基础类型直接赋值
                        fWrite.write(f"\toutputdata.{varName}()=data->{varName};\n")
                    elif varType in self.IDLStructMap.keys():#已定义的结构体 调用函数赋值
                        fWrite.write(f"\tconvert{varType}Write(&(data->{varName}),outputdata.{varName}());\n")
                    else:
                        print(f"\n不正常错误!!!!!!!!\n已通过的结构体{structName}出现未被识别的变量类型{varType}!!!!!")
                fWrite.write('}\n')

                fWrite.write(f"\nvoid convert{structName}Read({structName}* dstdata,{self.moduleName}::{structName}& outputdata)\n")
                fWrite.write('{\n')
                for var in vars:
                    varName = var["varName"]
                    varType = var["varType"]
                    if varType in self.IDLReflectMap.values():#基础类型直接赋值
                        fWrite.write(f"\tdstdata->{varName}=outputdata.{varName}();\n")
                    elif varType in self.IDLStructMap.keys():#已定义的结构体 调用函数赋值
                        fWrite.write(f"\tconvert{varType}Read(&(dstdata->{varName}),outputdata.{varName}());\n")
                    else:
                        print(f"\n不正常错误!!!!!!!!\n已通过的结构体{structName}出现未被识别的变量类型{varType}!!!!!")
                fWrite.write('}\n')

    #生成Write赋值函数调用代码
    def generateWriteCode(self):
        with open('resCode.txt', 'a+', encoding='utf-8') as fWrite:
            fWrite.write(f"\n\n//Write赋值函数调用代码\n")
            for structName in self.writeStructQueue:
                fWrite.write(f"\tconvert{structName}Write(data.XXX,outdata.YYY());\n")

    #生成Read赋值函数调用代码
    def generateReadCode(self):
        with open('resCode.txt', 'a+', encoding='utf-8') as fWrite:
            fWrite.write(f"\n\n//Read赋值函数调用代码\n")
            for structName in self.writeStructQueue:
                fWrite.write(f"\tconvert{structName}Read(dstdata.XXX,outdata.YYY());\n")


    # 结构体按需排序 被依赖的定义放前边
    def sortStruct(self):
        #主结构体队列不为空则持续循环
        flag=1
        while len(self.mainStructList) and flag:
            flag=False  #判断此次循环是否做出有效行为的标志(找不到定义)
            # 对每个结构体 判断其内部数据的类型是否均已知 否则往后排队
            for structName in self.mainStructList:
                if self.checkNoAllWrited(structName):
                    #不在则排队
                    self.mainStructList.remove(structName)
                    self.mainStructList.append(structName)
                    
                else:
                    self.writeStructQueue.append(structName)
                    self.mainStructList.remove(structName)
                    print(f"{structName}完成！")
                    flag = True


    #启动
    def run(self):
        with open("code.txt",'r',encoding="utf-8") as fRead:
            self.parseCode(fRead.read())
            self.sortStruct()
            self.generateIDL()
            self.generateFun()
            for structName in self.mainStructList:
                for var in self.IDLStructMap[structName]:
                    varType=var["varType"]
                    if varType not in self.IDLStructMap.keys() and varType not in self.IDLReflectMap.values():
                         print(f"{structName}存在未被定义的变量类型{varType}！")

            print('ok!')

if __name__ == '__main__':
    t=foxgloveTransformTool()
    t.run()
